package web.common.core.util;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Jin Zheng
 * @since 1.0 2021-12-29
 */
public class StringUtil {
	private static final String SPLIT = "[\\s,;\\|]";

	private StringUtil() {
	}

	/**
	 * 根据模板生成字符串，${variable:defaultValue}
	 *
	 * @param template 模板
	 * @param param    参数
	 * @return 生成的字符串
	 */
	public static String template(String template, Map<String, ?> param) {
		return template(template, param, "${", "}", ":");
	}

	/**
	 * 根据模板生成字符串，{index:defaultValue}
	 *
	 * @param template 模板
	 * @param args 参数
	 * @return 生成的字符串
	 */
	public static String template(String template, Object...args) {
		Map<String, Object> param = new HashMap<>();
		for (int i = 0; i < args.length; i++) {
			param.put(String.valueOf(i), args[i]);
		}
		return template(template, param, "{", "}", ":");
	}

	/**
	 * 根据模板生成字符串
	 *
	 * @param template 模板
	 * @param param    参数
	 * @param prefix   变量前缀
	 * @param suffix   变量后缀
	 * @param split  变量分栏符
	 * @return 生成的字符串
	 */
	public static String template(String template, Map<String, ?> param, String prefix, String suffix, String split) {
		AssertUtil.notEmpty(template, "模板");
		AssertUtil.notEmpty(param, "参数");
		AssertUtil.notEmpty(prefix, "前缀");
		AssertUtil.notEmpty(suffix, "后缀");

		StringBuilder content = new StringBuilder(template.length() * 2);
		int startPos = template.indexOf(prefix);
		int endPos = template.indexOf(suffix, startPos);
		while (startPos != -1 && endPos > startPos + prefix.length()) {
			content.append(template.substring(0, startPos));
			String placeholder = template.substring(startPos + prefix.length(), endPos);
			String defaultValue = "";

			if (split != null && !split.isEmpty()) {
				int defaultValuePos = placeholder.indexOf(split);
				if (defaultValuePos != -1) {
					defaultValue = placeholder.substring(defaultValuePos + split.length());
					placeholder = placeholder.substring(0, defaultValuePos);
				}
			}

			Object paramValue = param.get(placeholder);
			if (paramValue == null || "".equals(paramValue)) {
				paramValue = defaultValue;
			}
			content.append(paramValue);

			template = template.substring(endPos + suffix.length());
			startPos = template.indexOf(prefix);
			endPos = template.indexOf(suffix, startPos);
		}
		if (endPos == -1 || endPos < startPos + prefix.length()) {
			content.append(template);
		} else {
			content.append(template.substring(endPos + suffix.length()));
		}
		return content.toString();
	}

	/**
	 * 从类所在模块路径文件读取文本
	 *
	 * @param clazz     类
	 * @param classpath 类路径文件
	 * @return 读取的文本
	 */
	public static String getString(Class<?> clazz, String classpath) {
		if (classpath == null || classpath.isEmpty()) {
			return null;
		}

		if (clazz == null) {
			clazz = StringUtil.class;
		}
		InputStream is = clazz.getResourceAsStream(classpath);
		if (is == null) {
			ClassLoader loader = Thread.currentThread().getContextClassLoader();
			String path = classpath;
			if (classpath.startsWith("/")) {
				path = classpath.substring(1);
			}
			is = loader.getResourceAsStream(path);
		}
		String str = null;
		try (InputStream in = is) {
			byte[] buf = in.readAllBytes();
			str = new String(buf, StandardCharsets.UTF_8);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 连接字符串
	 *
	 * @param list      字符串列表
	 * @param separator 分割符
	 * @return 连接后的字符串
	 */
	public static String join(Collection<?> list, String separator) {
		if (list == null || list.isEmpty()) {
			return null;
		}

		String sep = separator == null ? "" : separator;
		StringBuilder concat = new StringBuilder();
		for (Object obj : list) {
			concat.append(obj).append(sep);
		}
		if (concat.length() > sep.length()) {
			concat.delete(concat.length() - sep.length(), concat.length());
		}
		return concat.toString();
	}

	/**
	 * 获取Jdbc类型，jdbc:mysql://localhost:3306/yourDBName => mysql
	 *
	 * @param jdbcUrl
	 * @return
	 */
	public static String getJdbcType(String jdbcUrl) {
		if (jdbcUrl == null || jdbcUrl.isEmpty()) {
			return null;
		}

		int len = 5;
		int index = jdbcUrl.indexOf(":", len);
		if (index == -1) {
			return null;
		}

		String jdbcType = jdbcUrl.substring(len, index);
		return jdbcType;
	}

	/**
	 * 产生重复字符串
	 *
	 * @param item      重复项
	 * @param times     重复次数
	 * @param separator 分割符
	 * @return 重复字符串
	 */
	public static String repeat(String item, int times, String separator) {
		AssertUtil.notEmpty(item, "Item");
		AssertUtil.positive(times, "Times");

		String sep = separator == null ? "" : separator;
		StringBuilder concat = new StringBuilder();
		for (int i = 0; i < times; i++) {
			concat.append(item).append(sep);
		}
		if (concat.length() > sep.length()) {
			concat.delete(concat.length() - sep.length(), concat.length());
		}
		return concat.toString();
	}

	/**
	 * 把 "5, 10, 50, 100, 150, 200, 500, 1000, 2000, 5000" 分割成字符串列表
	 *
	 * @param str 待分割字符串
	 * @return 字符串列表
	 */
	public static List<String> split(String str) {
		List<String> list = new ArrayList<>();
		if (str == null || str.isEmpty()) {
			return list;
		}

		for (String s : str.split(SPLIT)) {
			s = s.trim();
			if (s.isEmpty()) {
				continue;
			}

			list.add(s);
		}
		return list;
	}

}
